/**
 * 系统监控自动加载器
 * 在ComfyUI界面中自动添加系统监控显示
 */

import { app } from "/scripts/app.js";

const CONSOLE_PREFIX = "[SystemMonitor]";

// 注入CSS样式
function injectStyles() {
    const styles = `
        .system-monitor-menu-group {
            display: flex;
            flex-direction: column; 
            gap: 2px;
            margin: 0 10px;
        }

        .system-monitor-buttons-container {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .system-monitor-item {
            display: flex;
            align-items: center;
            gap: 5px;
            padding: 2px 8px;
            background-color: var(--comfy-input-bg, #333);
            border: 1px solid var(--comfy-input-border, #444);
            border-radius: 4px;
            font-size: 11px;
            color: var(--comfy-text, #ccc);
            cursor: default;
            transition: all 0.2s ease;
            position: relative; /* For progress bar */
            overflow: hidden;
        }
        
        .system-monitor-item:hover {
            background-color: var(--comfy-input-bg-hover, #444);
            border-color: var(--comfy-input-border-hover, #555);
        }

        .monitor-label {
            font-weight: bold;
            color: var(--comfy-text-highlight, #fff);
        }

        .system-monitor-cpu .monitor-label { color: #8ac926; }
        .system-monitor-memory .monitor-label { color: #ffca3a; }
        .system-monitor-gpu .monitor-label { color: #1982c4; }

        .monitor-details {
            font-family: monospace;
            font-size: 11px;
            color: var(--comfy-text, #ccc);
        }
        
        .system-monitor-cpu .monitor-progress-bar { background-color: #8ac926; }
        .system-monitor-memory .monitor-progress-bar { background-color: #ffca3a; }
        .system-monitor-gpu .monitor-progress-bar { background-color: #1982c4; }

        .monitor-progress-bar {
            height: 2px;
            width: 0%;
            border-radius: 2px;
            transition: width 0.5s ease, background-color 0.3s ease;
            position: absolute;
            bottom: 0;
            left: 0;
        }
        
        .monitor-progress-bar.normal { background: #2ecc71; }
        .monitor-progress-bar.warning { background: #f1c40f; }
        .monitor-progress-bar.critical { background: #e74c3c; }

        .system-monitor-slider-container {
            display: flex;
            align-items: center;
            gap: 5px;
            padding: 0;
            background-color: transparent;
            border: none;
            font-size: 9px;
            color: var(--comfy-text, #ccc);
        }

        .system-monitor-slider-label {
            white-space: nowrap;
            font-weight: bold;
            color: var(--comfy-text-highlight, #fff);
        }

        .system-monitor-slider {
            flex: 1;
            min-width: 80px;
            height: 4px;
            background: transparent;
            outline: none;
            -webkit-appearance: none;
            appearance: none;
            cursor: pointer;
        }

        .system-monitor-slider::-webkit-slider-runnable-track {
            height: 1px;
            background: var(--comfy-input-border-hover, #555);
            border-radius: 1px;
        }

        .system-monitor-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            margin-top: -2px;
            width: 5px;
            height: 5px;
            background: var(--comfy-text-highlight, #fff);
            border-radius: 50%;
            cursor: pointer;
        }

        .system-monitor-slider::-moz-range-track {
            height: 1px;
            background: var(--comfy-input-border-hover, #555);
            border-radius: 1px;
        }

        .system-monitor-slider::-moz-range-thumb {
            width: 5px;
            height: 5px;
            background: var(--comfy-text-highlight, #fff);
            border-radius: 50%;
            cursor: pointer;
            border: none;
        }

        .system-monitor-slider-interval-display {
            min-width: 40px;
            text-align: right;
            font-family: monospace;
            font-size: 9px;
            color: var(--comfy-text, #ccc);
        }
    `;
    const styleSheet = document.createElement("style");
    styleSheet.type = "text/css";
    styleSheet.innerText = styles;
    document.head.appendChild(styleSheet);
}

// 格式化字节数
function formatBytes(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}

// 创建监控元素
function createMonitorElement(type, label) {
    const item = document.createElement('div');
    item.className = `system-monitor-item system-monitor-${type}`;
    item.id = `system-monitor-${type}`;
    
    const labelEl = document.createElement('span');
    labelEl.className = 'monitor-label';
    labelEl.textContent = `${label}:`;
    
    const detailsEl = document.createElement('span');
    detailsEl.className = 'monitor-details';
    detailsEl.textContent = '...';

    const progressBar = document.createElement('div');
    progressBar.className = 'monitor-progress-bar';
    
    item.appendChild(labelEl);
    item.appendChild(detailsEl);
    item.appendChild(progressBar);
    
    return item;
}

// 更新监控元素
function updateMonitorElement(type, percentage, details) {
    const item = document.getElementById(`system-monitor-${type}`);
    if (!item) return;

    const detailsEl = item.querySelector('.monitor-details');
    if (detailsEl) {
        detailsEl.textContent = details;
        detailsEl.title = `${percentage.toFixed(1)}%`;
    }
    
    const progressBar = item.querySelector('.monitor-progress-bar');
    if (progressBar) {
        progressBar.style.width = `${percentage}%`;
    }
}

// 系统监控类
class SystemMonitor {
    constructor() {
        this.isInitialized = false;
        this.isMonitoring = false;
        this.monitorElements = {};
        this.updateInterval = null;
        this.lastUpdateTime = null;
        this.lastData = null;
        this.dataCallbacks = [];
        this.updateIntervalMs = 1000; // 默认1秒
        this.sliderElement = null;
        this.intervalDisplayElement = null;
    }
    
    setDisconnectedState() {
        for (const key in this.monitorElements) {
            const item = this.monitorElements[key];
            if (!item) continue;
            const detailsEl = item.querySelector('.monitor-details');
            if (detailsEl) {
                detailsEl.textContent = 'Disconnected';
                detailsEl.title = 'Server connection lost';
            }
            const progressBar = item.querySelector('.monitor-progress-bar');
            if (progressBar) {
                progressBar.style.width = '0%';
            }
        }
    }
    
    createMonitorUI(parentMenu) {
        if (document.querySelector('.system-monitor-menu-group')) {
            return;
        }

        const group = document.createElement('div');
        group.className = 'system-monitor-menu-group';

        const buttonsContainer = document.createElement('div');
        buttonsContainer.className = 'system-monitor-buttons-container';
        this.monitorElements.memory = createMonitorElement('memory', 'RAM');
        this.monitorElements.gpu = createMonitorElement('gpu', 'GPU');
        this.monitorElements.cpu = createMonitorElement('cpu', 'CPU');
        buttonsContainer.appendChild(this.monitorElements.gpu);
        buttonsContainer.appendChild(this.monitorElements.memory);
        buttonsContainer.appendChild(this.monitorElements.cpu);

        const sliderContainer = document.createElement('div');
        sliderContainer.className = 'system-monitor-slider-container';
        
        const sliderLabel = document.createElement('span');
        sliderLabel.className = 'system-monitor-slider-label';
        sliderLabel.textContent = '更新频率:';

        this.sliderElement = document.createElement('input');
        this.sliderElement.type = 'range';
        this.sliderElement.className = 'system-monitor-slider';
        this.sliderElement.min = '1';
        this.sliderElement.max = '30';
        this.sliderElement.step = '0.1';
        this.sliderElement.value = '1';
        this.sliderElement.title = '调整系统监控更新频率 (0.1-30秒)';
        
        this.intervalDisplayElement = document.createElement('span');
        this.intervalDisplayElement.className = 'system-monitor-slider-interval-display';
        this.intervalDisplayElement.textContent = '1s';
        
        this.sliderElement.addEventListener('input', (e) => {
            const value = parseFloat(e.target.value);
            this.updateIntervalMs = value * 1000;
            this.intervalDisplayElement.textContent = `${value}s`;
            if (this.isMonitoring) {
                this.restartMonitoring();
            }
        });

        sliderContainer.appendChild(sliderLabel);
        sliderContainer.appendChild(this.sliderElement);
        sliderContainer.appendChild(this.intervalDisplayElement);
        
        group.appendChild(buttonsContainer);
        group.appendChild(sliderContainer);

        const rightMenu = parentMenu.querySelector(".comfyui-menu-right");
        if (rightMenu) {
            parentMenu.insertBefore(group, rightMenu);
        } else {
            parentMenu.appendChild(group);
        }
        
        this.isInitialized = true;
    }
    
    restartMonitoring() {
        if (this.updateInterval) {
            clearInterval(this.updateInterval);
        }
        
        this.updateInterval = setInterval(() => {
            this.updateSystemStatus();
        }, this.updateIntervalMs);
    }
    
    startMonitoring() {
        if (this.isMonitoring) {
            return;
        }
        this.isMonitoring = true;
        
        // 立即执行一次
        (async () => {
            try {
                await this.updateSystemStatus();
            } catch (e) {
                console.error(`${CONSOLE_PREFIX} 首次更新执行失败`, e);
            }
        })();
        
        // 设置定时器
        this.updateInterval = setInterval(() => {
            this.updateSystemStatus();
        }, this.updateIntervalMs);
    }
    
    async updateSystemStatus() {
        if (!this.isMonitoring) return;
        
        this.lastUpdateTime = new Date();

        try {
            const response = await fetch('/system/status');

            if (!response.ok) {
                const errorText = await response.text();
                console.error(`${CONSOLE_PREFIX} API响应不成功 (状态码: ${response.status})，响应体:`, errorText);
                throw new Error(`API请求失败: ${response.status}`);
            }
            
            const data = await response.json();
            this.lastData = data;

            if (data && data.memory && data.cpu && data.gpu) {
                if (data.memory) {
                    updateMonitorElement('memory', data.memory.percent, `${data.memory.percent.toFixed(1)}%`);
                }
                if (data.gpu && Object.keys(data.gpu).length > 0) {
                    const firstGpu = data.gpu[Object.keys(data.gpu)[0]];
                    updateMonitorElement('gpu', firstGpu.percent, `${firstGpu.percent.toFixed(1)}%`);
                } else {
                    updateMonitorElement('gpu', 0, 'N/A');
                }
                if (data.cpu) {
                    updateMonitorElement('cpu', data.cpu.percent, `${data.cpu.percent.toFixed(1)}%`);
                }
            } else {
                console.error(`${CONSOLE_PREFIX} 从API获取的数据格式不正确或缺少关键字段。收到的数据:`, data);
                throw new Error("从API获取的数据格式不正确");
            }

            // 调用所有已注册的回调
            if (this.dataCallbacks.length > 0) {
                for (const cb of this.dataCallbacks) {
                    try {
                        cb(data);
                    } catch (e) {
                        console.error(`${CONSOLE_PREFIX} 执行数据回调时出错:`, e);
                    }
                }
            }

        } catch (error) {
            console.error(`${CONSOLE_PREFIX} 更新系统状态时出错:`, error);
            this.setDisconnectedState();
            this.stopMonitoring();
        } finally {
            this.lastUpdateTime = Date.now();
        }
    }
    
    destroy() {
        if (this.updateInterval) {
            clearInterval(this.updateInterval);
        }
        
        const group = document.querySelector('.system-monitor-menu-group');
        if (group) {
            group.remove();
        }
        
        this.isInitialized = false;
    }
    
    // 获取调试信息
    getDebugInfo() {
        return {
            monitorState: {
                isMonitoring: this.isMonitoring,
                lastUpdate: this.lastUpdateTime,
                lastData: this.lastData,
                updateInterval: this.updateInterval
            }
        };
    }

    registerDataCallback(callback) {
        if (typeof callback === 'function') {
            this.dataCallbacks.push(callback);
        }
    }

    unregisterDataCallback(callback) {
        this.dataCallbacks = this.dataCallbacks.filter(cb => cb !== callback);
    }
}

// 使用ComfyUI的扩展API进行注册
app.registerExtension({
    name: "Comfy.SystemMonitor",
    async setup() {
        injectStyles();
        
        const monitor = new SystemMonitor();
        window.SystemMonitorInstance = monitor;
        
        const parentMenu = document.querySelector(".comfyui-menu");
        if (parentMenu) {
            monitor.createMonitorUI(parentMenu);
            monitor.startMonitoring();
        } else {
            console.error(`${CONSOLE_PREFIX} 无法找到顶层菜单容器 (.comfyui-menu)，UI无法加载。`);
        }

        const originalQueuePrompt = app.queuePrompt;
        app.queuePrompt = async function(...args) {
            if (monitor.dataCallbacks.length > 0) {
                const resetSignal = { type: 'reset' };
                for (const cb of monitor.dataCallbacks) {
                    cb(resetSignal);
                }
            }
            return originalQueuePrompt.apply(this, args);
        };
    },
}); 